
luachip.parseCode = function(raw)
	local self = luachip
	
	
	local proc = ""
	for i = 1,#raw do
		local chr = raw:sub(i,i)
		if self.charIsValid(chr) or self.charIsWhite(chr) then
			proc = proc..chr
		end
	end
	proc = proc .. " "
	
	local phrasecode = {}
	
	local pS = 1
	local pE = 1
	for i = 1,#proc do
		local chr = proc:sub(i,i)
		if pS and self.charIsWhite(chr) then
			local phrase = proc:sub(pS,pE)
			table.insert(phrasecode,phrase)
			table.insert(phrasecode,chr)
			pS = nil
		else
			pS = pS or i
			pE = i
		end
	end
	
	//TODO:Strip comments
	//Mistakes to avoid: Comment marker inside parsed string
	
	//Break up code
	local i = 1
	repeat
		//Do we need to break it up? (Operators)
		luachip.breakphrase(phrasecode,i)
		i = i+1
	until i == #phrasecode+1
	
	//We now have the phrasecode with whitespace
	Msg("===UNPROCESSED===\n")
	PrintTable(phrasecode)
	
	do
		//Sanitize strings (This is where you look for exploits, JetBoom) t('.'t)
		//This is pretty much like driving backwards until you hit a brick wall, only you warp outside the other side of a corresponding brick wall and don't actually collide, then save everything between those two particular brick walls, an exception being that the brick walls might actually be made of clay or concrete, in which case you would warp out of a clay or concrete wall, respectively.
		
		local ignore = ignore or {}
		
		for i=#phrasecode,1,-1 do
			for k,v in pairs{
				"'",
				'"',
				{
					"[[",
					"]]",
				}
			} do
				if not ignore[i] then
					local dS,dE
					if type(v) == "string" then
						dS,dE = v,v
					else
						dS,dE = unpack(v)
					end
					if phrasecode[i] == dE then
						local s = self.matchPairRaw(phrasecode,1,i,dS,dE,nil,true)
						if s then
							local str = ""
							for string=i,s,-1 do
								str = phrasecode[string] ..str
								ignore[string] = true
								table.remove(phrasecode,string)
								i = i-1
							end
							
							//Make sure the string has acceptable escape characters
							
							if not self.isValidString(str) then
								Msg("[ERROR] Tried to instantiate an illegal string!\n")
								return false
							end
							
							//M/sg("Added ",str,"\n")
							table.insert(phrasecode,i+1,str) //Since we are working from right to left, this is perfectly fine
						else
							return false //We have an unmatched brace
						end
					end
				end
			end
		end
		
		/*
		local oldphrasecode = phrasecode
		phrasecode = {}
		
		for k,v in pairs(oldphrasecode) do
			if not ignore[k] then
				table.insert(phrasecode,v)
			end
		end
		*/
	end
	
	//Trim phrases
	local i = 1
	repeat
		phrasecode[i] = string.Trim(phrasecode[i])
		i =i+1
	until i == #phrasecode+1
	
	//Remove whitespace phrases
	local i = 1
	repeat
		local phrase = phrasecode[i]
		if self.charIsWhite(phrase) or phrase == "" then
			table.remove(phrasecode,i)
			i = i-1
		end
		i = i+1
	until i == #phrasecode+1
	
	//Make all keywords lower case
	local i = 1
	repeat
		luachip.lowerkeywords(phrasecode,i)
		i = i+1
	until i == #phrasecode+1
	
	//We now have the phrasecode without whitespace
	//M/sg("PHRASECODE WITHOUT WHITESPACE:\n")
	//P/rintTable(phrasecode)
	
	Msg("\n===FINPHRASING===\n\n")
	PrintTable(phrasecode)
	
	//Parse
	local i = 1
	local pS = 1
	local pE = 1
	local pDecFunc = false
	local pNextOperatorAllowed = false
	
	local pGlobals = {}
	local ignore = {}
	
	Msg("\n===Parsing===\n")
	repeat
		local phrase = phrasecode[i]
		Msg("[",i,"]")
		
		if not ignore[i] then
			Msg("\t",phrase,"\n")
			if not luachip.isValidPhrase(phrasecode,i,pGlobals,ignore) then
				return false
			end
		else
			Msg("[SKIP]\t",phrase,"\n")
		end
		
		i = i+1
	until i == #phrasecode+1
	
	Msg("\n===UNPARSED===\n\n")
	for k,v in pairs(phrasecode) do
		if not ignore[k] then
			Msg("[",k,"]\t",v,"\n")
		end
	end
	
	Msg("\n===GLOBALS===\n\n")
	PrintTable(pGlobals)
	
	//Phase the phrasecode
	local final = ""
	for k,v in pairs(phrasecode) do
		
		if tostring(v) ~= "" then
			if (self.isLibraryVar(v) or self.isLocalVar(v)) and k+1 < #phrasecode and phrasecode[k+1] == "." and self.isLocalVar(phrasecode[k+2]) then
				phrasecode[k] = v .. "." .. phrasecode[k+2]
				phrasecode[k+1] = ""
				phrasecode[k+2] = ""
				
				v = phrasecode[k]
			end
			if ({
				["local"] = true,
				["if"] = true,
				["while"] = true,
				["for"] = true,
				["else"] = true,
				["elseif"] = true,
				["end"] = true,
				["return"] = true,
				["break"] = true,
			})[v] then
				final = final.."\n"
			end
			
			final = final .. tostring(v) .. " "
			
			if ({
				["then"] = true,
				["do"] = true,
				["else"] = true,
				["elseif"] = true,
				["end"] = true,
				["and"] = true,
				["or"] = true,
				["break"] = true,
			})[v] then
				final = final.."\n"
			end
		end
	end
	finalcode = final .. "\n"
	final = ""
	final = final.."_pl = luachip.procpl\n"
	final = final.."_self = luachip.procent\n"
	
	//Add the library references
	for k,v in pairs(self.library) do
		if type(v) == "table" then
			if type(k) == "string" then
				final = "local ".. k .." = {}\n"..
				"setmetatable("..k..",{__newindex = ErrorNoHalt,__index = function(self,k) return luachip.library."..k.."[k] end})\n"..final
				pGlobals[k] = nil
			end
		else
			if type(k) == "string" then
				final = "local ".. k .." = luachip.library."..k.."\n"..final
				pGlobals[k] = nil
			end
		end
	end
	
	//Add metaglobals
	final = final .. "//MetaGlobals\n\n"
	
	local mg = {}
	local depth = 0
	local processMetaGlobal
	processMetaGlobal = function(i,depth)
		for k,v in pairs(i) do
			
			if type(v) == "string" then
				table.insert(mg,string.rep("\t",depth)..(depth > 0 and "" or "local ")..k.." = (function(self,pl) local plid = pl local pl = player.GetByUniqueID(pl) pl = pl and IsEntity(pl) and pl:IsPlayer() and pl:IsConnected() and pl or nil local f = \n"..tostring(v).."\n"..string.rep("\t",depth).."return f end)(luachip.procent,luachip.procpl)"..(depth > 0 and "," or "").."\n")
				
				if depth == 0 then
					pGlobals[k] = nil
				end
			else
				if depth > 0 then
					table.insert(mg,string.rep("\t",depth)..k.." = {\n")
					processMetaGlobal(v,depth+1)
					table.insert(mg,string.rep("\t",depth).."},\n")
				else
					pGlobals[k] = nil
					
					table.insert(mg,"local "..k.." = {\n")
					processMetaGlobal(v,depth+1)
					table.insert(mg,"}\n")
				end
			end
			
		end
	end
	processMetaGlobal(luachip.metaglobals,depth)
	
	local out = ""
	for k,v in pairs(mg) do
		out = out..v
	end
	final = final..out
	
	//Add fetched functions from meta after allocation
	final = final .. "//MetaLibrary\n\n"
	final = final.."self = luachip.procent\n"
	final = final.."pl = luachip.procpl\n"
	for k,v in pairs(luachip.metalibrary) do
		final = final..tostring(v).."\n"
	end
	
	//Add the self references
	final = final.."local self = __entity.GetNent(luachip.procent)\n"
	final = final.."local pl = luachip.procpl\n"
	
	//Add the locals
	for k,v in pairs(pGlobals) do
		final = final.."local ".. k .."\n"
	end
	
	//Get the starting code line
	local dbgline = #string.Explode("\n",final)
	
	//Add the code
	final = "do\n"..final.."\ndo\n"..finalcode.."\nend\nend\n"
	
	Msg("\n===FINAL===\n\n")
	local pr = string.Explode("\n",final)
	for i = imdebuggingluachip and 1 or dbgline,#pr do
		Msg(i,"\t\t:\t",pr[i],"\n")
	end
	//PrintTable(pr)
	
	return final
	/*
	//EXECUTE!!! MUHAHHAHAHHAHAHAH
	Msg("\n===EXECUTING===\n\n")
	RunString(final)
	*/
end

luachip.lowerkeywords = function(phrasecode,i)
	if luachip.isKeyword(phrasecode[i]) then
		phrasecode[i] = phrasecode[i]:lower()
	end
end

luachip.breakphrase = function(phrasecode,i)
	local self = luachip
	local phrase = phrasecode[i]
	//M/sg("\tBreaking ",phrase," (",i,")\n")
	if self.isOperatorOrStringOperator(phrase) or self.isKeyword(phrase) then
		return
	end
	
	//Find operators
	for k,v in pairs(luachip.operatorsOrStringOperators) do
		local a,ab = phrase:find(k,nil,true)
		if a then
			//Precedence of longer operators (So we don't split a longer operator
			local fail = false
			for i,o in pairs(luachip.operatorsOrStringOperators) do
				if #i > #k then
					local ac,ad = phrase:find(i,nil,true)
					
					if ac then
						if ac == a then
							//This is a quicker way of doing business
							fail = true
							break
						end
						
						local conf = {}
						for i=ac,ad do
							conf[i] = true
						end
						for i=a,ab do
							if conf[i] then
								//M/sg("\t\tFAILED ",k," INTERCEPTED ",i,"!\n")
								fail = true
								break
							end
						end
					end
				end
			end
			
			if not fail then
				//Split
				
				local sL = (a-1 > 0) and phrase:sub(1,a-1) or ""
				local sM = phrase:sub(a,a+#k-1)
				local sR = (#phrase >= a+#k) and phrase:sub(a+#k) or ""
				//M/sg("\t\tsL == ",sL,"\n")
				//M/sg("\t\tsM == ",sM,"\n")
				//M/sg("\t\tsR == ",sR,"\n")
				
				if sR ~= "" then
					table.insert(phrasecode,i+1,sR)
					self.breakphrase(phrasecode,i+1)
				end
				if sM ~= "" then
					table.insert(phrasecode,i+1,sM)
					self.breakphrase(phrasecode,i+1)
				end
				if sL ~= "" then
					table.insert(phrasecode,i+1,sL)
					self.breakphrase(phrasecode,i+1)
				end
				
				table.remove(phrasecode,i)
				i = i-1
				
				break
			end
		end
	end
end

if SERVER then
end

if CLIENT then
end
